using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.ComponentModel.Design;

namespace ExtControl
{
    [
    Designer(typeof(FormBaseDesigner))
    ]
    public partial class FrmBase : DevExpress.XtraEditors.XtraForm
    {
        #region variant
        private bool allowZising = true;
        private bool showCloseButton = true;
        private bool showMaxButton = true;
        private bool allowMove = true;
        private bool isMaximize = false;
        public bool allowCloseForm = true;

        private Point mouseDragInitialPosition;
        private bool drag = false;
        private bool press = false;

        private int formLeft = 0;
        private int formTop = 0;
        private int formWidth = 0;
        private int formHeight = 0;
        private int formMinHeight = 0;
        private int formMaxHeight = 0;
        private int formMinWidth = 0;
        private int formMaxWidth = 0;

        private int mainLeft = 0;
        private int mainTop = 0;
        private int mainWidth = 0;
        private int mainHeght = 0;

        private Control form = null;
        private Control mainForm = null;
        #endregion variant

        public FrmBase()
        {
            InitializeComponent();

            //close button
            this.pnClose.MouseLeave += new EventHandler(pnClose_MouseLeave);
            this.pnClose.MouseEnter += new EventHandler(pnClose_MouseEnter);
            this.pnClose.MouseDown += new MouseEventHandler(pnClose_MouseDown);
            this.pnClose.MouseUp += new MouseEventHandler(pnClose_MouseUp);

            //maximize button
            this.pnMax.MouseLeave += new EventHandler(pnMax_MouseLeave);
            this.pnMax.MouseEnter += new EventHandler(pnMax_MouseEnter);
            this.pnMax.MouseDown += new MouseEventHandler(pnMax_MouseDown);
            this.pnMax.MouseUp += new MouseEventHandler(pnMax_MouseUp);

            //restore button
            this.pnRestore.MouseLeave += new EventHandler(pnRestore_MouseLeave);
            this.pnRestore.MouseEnter += new EventHandler(pnRestore_MouseEnter);
            this.pnRestore.MouseDown += new MouseEventHandler(pnRestore_MouseDown);
            this.pnRestore.MouseUp += new MouseEventHandler(pnRestore_MouseUp);

            //pnHeader
            this.pnHeader.MouseDown += new MouseEventHandler(pnHeader_MouseDown);
            this.pnHeader.MouseMove += new MouseEventHandler(pnHeader_MouseMove);
            this.pnHeader.MouseUp += new MouseEventHandler(pnHeader_MouseUp);

            this.lblIconZ.MouseDown += new MouseEventHandler(pnHeader_MouseDown);
            this.lblIconZ.MouseMove += new MouseEventHandler(pnHeader_MouseMove);
            this.lblIconZ.MouseUp += new MouseEventHandler(pnHeader_MouseUp);

            this.lblTitleZ.MouseDown += new MouseEventHandler(pnHeader_MouseDown);
            this.lblTitleZ.MouseMove += new MouseEventHandler(pnHeader_MouseMove);
            this.lblTitleZ.MouseUp += new MouseEventHandler(pnHeader_MouseUp);

            //pnTopCentre
            this.pnTopCentre.MouseDown += new MouseEventHandler(pnTopCentre_MouseDown);
            this.pnTopCentre.MouseMove += new MouseEventHandler(pnTopCentre_MouseMove);
            this.pnTopCentre.MouseUp += new MouseEventHandler(pnTopCentre_MouseUp);

            //pnBottomCentre
            this.pnBottomCentre.MouseDown += new MouseEventHandler(pnBottomCentre_MouseDown);
            this.pnBottomCentre.MouseMove += new MouseEventHandler(pnBottomCentre_MouseMove);
            this.pnBottomCentre.MouseUp += new MouseEventHandler(pnBottomCentre_MouseUp);

            //pnLeftCentre
            this.pnLeft.MouseDown += new MouseEventHandler(pnLeft_MouseDown);
            this.pnLeft.MouseMove += new MouseEventHandler(pnLeft_MouseMove);
            this.pnLeft.MouseUp += new MouseEventHandler(pnLeft_MouseUp);

            //pnRightCentre
            this.pnRight.MouseDown += new MouseEventHandler(pnRight_MouseDown);
            this.pnRight.MouseMove += new MouseEventHandler(pnRight_MouseMove);
            this.pnRight.MouseUp += new MouseEventHandler(pnRight_MouseUp);

            //pnTopLeft
            this.pnTopLeft.MouseDown += new MouseEventHandler(pnTopLeft_MouseDown);
            this.pnTopLeft.MouseMove += new MouseEventHandler(pnTopLeft_MouseMove);
            this.pnTopLeft.MouseUp += new MouseEventHandler(pnTopLeft_MouseUp);

            //pnTopRight
            this.pnTopRight.MouseDown += new MouseEventHandler(pnTopRight_MouseDown);
            this.pnTopRight.MouseMove += new MouseEventHandler(pnTopRight_MouseMove);
            this.pnTopRight.MouseUp += new MouseEventHandler(pnTopRight_MouseUp);

            //pnBottomLeft
            this.pnBottomLeft.MouseDown += new MouseEventHandler(pnBottomLeft_MouseDown);
            this.pnBottomLeft.MouseMove += new MouseEventHandler(pnBottomLeft_MouseMove);
            this.pnBottomLeft.MouseUp += new MouseEventHandler(pnBottomLeft_MouseUp);

            //pnBottomRight
            this.pnBottomRight.MouseDown += new MouseEventHandler(pnBottomRight_MouseDown);
            this.pnBottomRight.MouseMove += new MouseEventHandler(pnBottomRight_MouseMove);
            this.pnBottomRight.MouseUp += new MouseEventHandler(pnBottomRight_MouseUp);
        }

        public void ShowForm(Control mainForm)
        {
            this.TopLevel = false;

            this.mainForm = mainForm;

            this.Left = mainForm.Width / 2 - this.Width / 2;
            this.Top = mainForm.Height / 2 - this.Height / 2 - 20;
            this.mainForm.Controls.Add(this);

            this.BringToFront();

            this.form = this;
        }

        private void GetInitInfo()
        {
            this.formLeft = this.form.Left;
            this.formTop = this.form.Top;

            this.formWidth = this.form.Width;
            this.formHeight = this.form.Height;

            this.mainWidth = this.mainForm.Width;
            this.mainHeght = this.mainForm.Height;

            this.mainLeft = this.mainForm.Left;
            this.mainTop = this.mainForm.Top;

            this.formMinHeight = this.form.MinimumSize.Height;
            this.formMaxHeight = this.form.MaximumSize.Height;

            this.formMinWidth = this.form.MinimumSize.Width;
            this.formMaxWidth = this.form.MaximumSize.Width;

            if (this.formMinHeight == 0)
                this.formMinHeight = 100;
            if (this.formMaxHeight == 0)
                this.formMaxHeight = this.mainHeght - this.formTop;

            if (this.formMinWidth == 0)
                this.formMinWidth = 150;
            if (this.formMaxWidth == 0)
                this.formMaxWidth = this.mainWidth;
        }

        private void Maximize()
        {
            if (isMaximize == false)
            {
                GetInitInfo();
                this.form.Left = -2;
                this.form.Top = this.mainForm.Top;
                this.form.Width = this.formMaxWidth;
                this.form.Height = this.formMaxHeight;

                this.pnMax.Visible = false;
                this.pnRestore.Visible = true;

                this.allowZising = false;
                this.allowMove = false;
                this.isMaximize = true;
                this.form.Update();
            }
        }

        private void Restore()
        {
            if (this.isMaximize == true)
            {
                this.form.Left = this.formLeft;
                this.form.Top = this.formTop;
                this.form.Width = this.formWidth;
                this.form.Height = this.formHeight;

                this.pnMax.Visible = true;
                this.pnRestore.Visible = false;

                this.allowZising = true;
                this.allowMove = true;
                this.isMaximize = false;
                this.form.Update();
            }
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
        }

        //============================================================================================
        #region close button
        private void pnClose_MouseLeave(object sender, EventArgs e)
        {
            if (this.allowCloseForm)
                if (!this.press)
                    this.pnClose.BackgroundImage = Properties.Resources.bgr_close1;
        }

        private void pnClose_MouseEnter(object sender, EventArgs e)
        {
            if (this.allowCloseForm)
                if (!this.press)
                    this.pnClose.BackgroundImage = Properties.Resources.bgr_close2;
        }

        private void pnClose_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.allowCloseForm)
            {
                this.pnClose.BackgroundImage = Properties.Resources.bgr_close3;
                this.press = true;
            }
        }

        private void pnClose_MouseUp(object sender, MouseEventArgs e)
        {
            this.press = false;

            if (this.allowCloseForm)
                if (e.X >= 0 && e.Y >= 0 && e.X <= this.pnClose.Width && e.Y <= this.pnClose.Height)
                {
                    this.Close();
                }
        }
        #endregion close button

        //============================================================================================
        #region maximize button
        private void pnMax_MouseLeave(object sender, EventArgs e)
        {
            if (!this.press)
                this.pnMax.BackgroundImage = Properties.Resources.bgr_max1;
        }

        private void pnMax_MouseEnter(object sender, EventArgs e)
        {
            if (!this.press)
                this.pnMax.BackgroundImage = Properties.Resources.bgr_max2;
        }

        private void pnMax_MouseDown(object sender, MouseEventArgs e)
        {
            this.pnMax.BackgroundImage = Properties.Resources.bgr_max3;
            this.press = true;
        }

        private void pnMax_MouseUp(object sender, MouseEventArgs e)
        {
            this.press = false;

            if (e.X >= 0 && e.Y >= 0 && e.X <= this.pnMax.Width && e.Y <= this.pnMax.Height)
            {
                Maximize();
            }
        }
        #endregion maximize button

        //============================================================================================
        #region restore button
        private void pnRestore_MouseLeave(object sender, EventArgs e)
        {
            if (!this.press)
                this.pnRestore.BackgroundImage = Properties.Resources.bgr_restore1;
        }

        private void pnRestore_MouseEnter(object sender, EventArgs e)
        {
            if (!this.press)
                this.pnRestore.BackgroundImage = Properties.Resources.bgr_restore2;
        }

        private void pnRestore_MouseDown(object sender, MouseEventArgs e)
        {
            this.pnRestore.BackgroundImage = Properties.Resources.bgr_restore3;
            this.press = true;
        }

        private void pnRestore_MouseUp(object sender, MouseEventArgs e)
        {
            this.press = false;

            if (e.X >= 0 && e.Y >= 0 && e.X <= this.pnRestore.Width && e.Y <= this.pnRestore.Height)
            {
                Restore();
            }
        }
        #endregion restore button

        //============================================================================================
        #region pnHeader
        private void pnHeader_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
            {
                GetInitInfo();

                this.mouseDragInitialPosition = MousePosition;
                this.drag = true;
            }
        }

        private void pnHeader_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int newLeft = this.formLeft + mouse.X - this.mouseDragInitialPosition.X;
                int newTop = this.formTop + mouse.Y - this.mouseDragInitialPosition.Y;

                if (newLeft >= 0 && newLeft <= this.mainWidth - this.formWidth)
                {
                    this.form.Left = newLeft;
                    this.form.Parent.Update();
                }

                if (newTop >= 0 && newTop <= this.mainHeght - this.formHeight - this.mainTop)
                {
                    this.form.Top = newTop;
                    this.form.Parent.Update();
                }
            }
        }

        private void pnHeader_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnHeader

        //============================================================================================
        #region pnTopCentre
        private void pnTopCentre_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnTopCentre_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int delta = mouse.Y - mouseDragInitialPosition.Y;
                int newTop = this.formTop + delta;
                int newHeight = this.formHeight - delta;

                if (newHeight >= this.formMinHeight && newHeight <= this.formMaxHeight)
                    if (newTop >= 0)
                    {
                        this.form.Top = newTop;
                        this.form.Height = newHeight;
                        this.form.Parent.Update();
                        this.form.Update();
                    }
            }
        }

        private void pnTopCentre_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnTopCentre

        //============================================================================================
        #region pnBottomCentre
        private void pnBottomCentre_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnBottomCentre_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int delta = mouse.Y - mouseDragInitialPosition.Y;
                int newHeight = this.formHeight + delta;

                if (newHeight >= this.formMinHeight && newHeight <= this.formMaxHeight)
                {
                    this.form.Height = newHeight;
                    this.form.Parent.Update();
                    this.form.Update();
                }
            }
        }

        private void pnBottomCentre_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnBottomCentre

        //============================================================================================
        #region pnLeftCentre
        private void pnLeft_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnLeft_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int delta = mouse.X - mouseDragInitialPosition.X;

                int newLeft = this.formLeft + delta;
                int newWidth = this.formWidth - delta;

                if (newWidth >= this.formMinWidth && newWidth <= this.formMaxWidth)
                    if (newLeft >= 0)
                    {
                        this.form.Left = newLeft;
                        this.form.Width = newWidth;
                        this.form.Parent.Update();
                        this.form.Update();
                    }
            }
        }

        private void pnLeft_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnLeftCentre

        //============================================================================================
        #region pnRightCentre
        private void pnRight_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnRight_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int delta = mouse.X - mouseDragInitialPosition.X;

                int newWidth = this.formWidth + delta;

                if (newWidth >= this.formMinWidth && newWidth <= this.formMaxWidth)
                {
                    this.form.Width = newWidth;
                    this.form.Parent.Update();
                    this.form.Update();
                }
            }
        }

        private void pnRight_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnRightCentre

        //============================================================================================
        #region pnTopLeft
        private void pnTopLeft_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnTopLeft_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int deltaX = mouse.X - mouseDragInitialPosition.X;
                int deltaY = mouse.Y - mouseDragInitialPosition.Y;

                int newTop = this.formTop + deltaY;
                int newHeight = this.formHeight - deltaY;

                int newLeft = this.formLeft + deltaX;
                int newWidth = this.formWidth - deltaX;

                if (newHeight >= this.formMinHeight && newHeight <= this.formMaxHeight)
                    if (newTop >= 0)
                    {
                        this.form.Top = newTop;
                        this.form.Height = newHeight;
                        this.form.Parent.Update();
                        this.form.Update();
                    }

                if (newWidth >= this.formMinWidth && newWidth <= this.formMaxWidth)
                    if (newLeft >= 0)
                    {
                        this.form.Left = newLeft;
                        this.form.Width = newWidth;
                        this.form.Parent.Update();
                        this.form.Update();
                    }
            }
        }

        private void pnTopLeft_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnTopLeft

        //============================================================================================
        #region pnTopRight
        private void pnTopRight_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnTopRight_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int deltaX = mouse.X - mouseDragInitialPosition.X;
                int deltaY = mouse.Y - mouseDragInitialPosition.Y;

                int newTop = this.formTop + deltaY;
                int newHeight = this.formHeight - deltaY;

                int newWidth = this.formWidth + deltaX;

                if (newHeight >= this.formMinHeight && newHeight <= this.formMaxHeight)
                    if (newTop >= 0)
                    {
                        this.form.Top = newTop;
                        this.form.Height = newHeight;
                        this.form.Parent.Update();
                        this.form.Update();
                    }

                if (newWidth >= this.formMinWidth && newWidth <= this.formMaxWidth)
                {
                    this.form.Width = newWidth;
                    this.form.Parent.Update();
                    this.form.Update();
                }
            }
        }

        private void pnTopRight_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnTopRight

        //============================================================================================
        #region pnBottomLeft
        private void pnBottomLeft_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnBottomLeft_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int deltaX = mouse.X - mouseDragInitialPosition.X;
                int deltaY = mouse.Y - mouseDragInitialPosition.Y;

                int newHeight = this.formHeight + deltaY;

                int newLeft = this.formLeft + deltaX;
                int newWidth = this.formWidth - deltaX;

                if (newHeight >= this.formMinHeight && newHeight <= this.formMaxHeight)
                {
                    this.form.Height = newHeight;
                    this.form.Parent.Update();
                    this.form.Update();
                }

                if (newWidth >= this.formMinWidth && newWidth <= this.formMaxWidth)
                    if (newLeft >= 0)
                    {
                        this.form.Left = newLeft;
                        this.form.Width = newWidth;
                        this.form.Parent.Update();
                        this.form.Update();
                    }
            }
        }

        private void pnBottomLeft_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnBottomLeft

        //============================================================================================
        #region pnBottomRight
        private void pnBottomRight_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.isMaximize == false)
                if (this.allowZising)
                {
                    GetInitInfo();

                    this.mouseDragInitialPosition = MousePosition;
                    this.drag = true;
                }
        }

        private void pnBottomRight_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                Point mouse = MousePosition;
                int deltaX = mouse.X - mouseDragInitialPosition.X;
                int deltaY = mouse.Y - mouseDragInitialPosition.Y;

                int newHeight = this.formHeight + deltaY;
                int newWidth = this.formWidth + deltaX;

                if (newHeight >= this.formMinHeight && newHeight <= this.formMaxHeight)
                {
                    this.form.Height = newHeight;
                    this.form.Parent.Update();
                    this.form.Update();
                }

                if (newWidth >= this.formMinWidth && newWidth <= this.formMaxWidth)
                {
                    this.form.Width = newWidth;
                    this.form.Parent.Update();
                    this.form.Update();
                }
            }
        }

        private void pnBottomRight_MouseUp(object sender, MouseEventArgs e)
        {
            this.drag = false;
        }
        #endregion pnBottomRight

        //============================================================================================
        #region Properties
        [
            Category("AllowZising"),
            Description("Set/Get allow sizing form")
        ]
        public bool AllowZising
        {
            set
            {
                this.allowZising = value;
            }
            get
            {
                return this.allowZising;
            }
        }

        [
            Category("ShowCloseButton"),
            Description("Show/Hide Close Button")
        ]
        public bool ShowCloseButton
        {
            set
            {
                this.showCloseButton = value;
                this.pnClose.Visible = this.showCloseButton;

                this.pnMax.Location = (this.showCloseButton ? new Point(0, 0) : this.pnClose.Location);
                this.pnRestore.Location = this.pnMax.Location;
            }
            get
            {
                return this.showCloseButton;
            }
        }

        [
            Category("ShowMaximizeButton"),
            Description("Show/Hide Maximize Button")
        ]
        public bool ShowMaximizeButton
        {
            set
            {
                this.showMaxButton = value;
                this.pnMax.Visible = this.showMaxButton;
                this.pnRestore.Visible = this.showMaxButton;
            }
            get
            {
                return this.showMaxButton;
            }
        }

        [
            Category("ExtIcon"),
            Description("Set/Get Icon")
        ]
        public Image ExtIcon
        {
            set
            {
                this.lblIconZ.Image = value;
                if (this.lblIconZ.Image == null)
                {
                    this.lblIconZ.Visible = false;
                    this.lblTitleZ.Left = 5;
                }
                else
                {
                    this.lblIconZ.Visible = true;
                    this.lblTitleZ.Left = 42;
                }
            }
            get
            {
                return this.lblIconZ.Image;
            }
        }

        [
            Category("ExtTitle"),
            Description("Set/Get Title")
        ]
        public string ExtTitle
        {
            set
            {
                this.lblTitleZ.Text = value;
            }
            get
            {
                return this.lblTitleZ.Text;
            }
        }

        [
        Category("Appearance"),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
        ]
        public Panel WorkingArea
        {
            get
            {
                return this.pnMain;
            }
        }
        #endregion Properties
    }
}